﻿using Serialization.Script;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using DrawableObjects.Actors.Aircrafts;
using WorldView;
using Sirian.DrawableObject.Actors;
using Microsoft.Xna.Framework;
using System.Collections.Generic;
using InterfaceComponents;
using DrawableObjects.Actors.Aircrafts.Controller;
using GlobalGameClasses;
using Microsoft.Xna.Framework.Graphics;
using Serialization;

namespace SirianTestEnvironment
{
    
    
    /// <summary>
    ///This is a test class for Event_CreateBossTest and is intended
    ///to contain all Event_CreateBossTest Unit Tests
    ///</summary>
    [TestClass()]
    public class Event_Tests
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        [ClassInitialize()]
        public static void MyClassInitialize(TestContext testContext)
        {
            System.Windows.Forms.Form form = new System.Windows.Forms.Form();
            form.Visible = false;
            form.ShowInTaskbar = false;
            PresentationParameters param = new PresentationParameters();
            param.DeviceWindowHandle = form.Handle;
            param.IsFullScreen = false;
            GraphicsDevice device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, GraphicsProfile.HiDef, param);
            GlobalGameClasses.GlobalGameValues.Values.graphicsDevice = device;
            GlobalGameClasses.GlobalGameValues.Values.spriteBatch = new SpriteBatch(device);
            GlobalGameValues.Values.content.addTexture("smokeTexture", new Texture2D(device, 1, 1));
            GlobalGameValues.Values.content.addTexture("health", new Texture2D(device, 1, 1));
            GlobalGameValues.Values.content.addContent("aircraft_enemy1", null, new Texture2D(device,1,1));
            GlobalGameValues.Values.content.addContent("aircraft_enemy2", null, new Texture2D(device, 1, 1));
            GlobalGameValues.Values.content.addContent("aircraft_enemy3", null, new Texture2D(device, 1, 1));
            GlobalGameValues.Values.content.addContent("aircraft_enemy4", null, new Texture2D(device, 1, 1));
            GlobalGameValues.Values.content.addContent("aircraft_enemy5", null, new Texture2D(device, 1, 1));
            GlobalGameClasses.GlobalGameValues.Values.content.addSong("song1", null);
        }
        //
        //Use ClassCleanup to run code after all tests in a class have run
        [ClassCleanup()]
        public static void MyClassCleanup()
        {
            GlobalGameValues.Values.achievementsUnlocked = new List<Achievement>();
            GlobalGameValues.Values.content = new ContentCollection();
            GlobalGameValues.Values.difficulty = null;
            GlobalGameValues.Values.errorWriter = null;
            GlobalGameValues.Values.gameTime = new GameTime();
            GlobalGameValues.Values.GlobalStrings = new StringContainer();
            GlobalGameValues.Values.graphicsDevice = null;
            GlobalGameValues.Values.score = new InterfaceComponents.HUDWrapper<int>(new List<InterfaceComponents.HUDComponent>());
            GlobalGameValues.Values.soundPlayer = null;
            GlobalGameValues.Values.spriteBatch = null;
            GlobalGameValues.Values.volume_Music = 0;
            GlobalGameValues.Values.volume_soundEffect = 0;
        }
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        /// <summary>
        ///A test for execute
        ///</summary>
        [TestMethod()]
        public void executeCreateBossTest()
        {
            Aircraft boss = FabricatableAircraft.GET_ENEMY_1(Matrix.Identity);
            int eventTime = 0; // TODO: Initialize to an appropriate value
            Event_CreateBoss target = new Event_CreateBoss(boss, eventTime); // TODO: Initialize to an appropriate value
            LevelScript levelScript = new LevelScript(new List<ScriptedEvent>());
            GenericDrawableList drawableList = new GenericDrawableList();
            List<InterfaceComponent> components = new List<InterfaceComponent>();
            World world = new World(new Serialization.AchievementHandler(0, ""), drawableList, components, levelScript);
            Bounding visibleArea = new Bounding(new Vector2(0, 0), 1200, 800, true);
            Bounding useableArea = new Bounding(new Vector2(-301, -300), 1802, 1101, true);
            target.execute(world, visibleArea, useableArea);
            Assert.AreEqual(drawableList.getActors(typeof(Aircraft))[0], boss);
            Assert.IsTrue(components[0] is Healthbar);
            Assert.IsTrue(boss.controller is AIControlledAircraft_Boss);
            Rectangle expectedArea = new Rectangle(-1, -300, 1202, 301);
            Point setPoint = new Point((int)boss.getGamePosition().X, (int)boss.getGamePosition().Y);
            Assert.IsTrue(expectedArea.Contains(setPoint));
        }

        [TestMethod()]
        public void executeCreateEnemyWaveTest()
        {
            List<Aircraft> enemies = new List<Aircraft>();
            enemies.Add(FabricatableAircraft.GET_ENEMY_1(Matrix.Identity));
            enemies.Add(FabricatableAircraft.GET_ENEMY_2(Matrix.Identity));
            enemies.Add(FabricatableAircraft.GET_ENEMY_3(Matrix.Identity));
            enemies.Add(FabricatableAircraft.GET_ENEMY_4(Matrix.Identity));
            enemies.Add(FabricatableAircraft.GET_ENEMY_5(Matrix.Identity));
            V_Formation formation = new V_Formation();
            List<Vector2> pathPoints = new List<Vector2>();
            pathPoints.Add(new Vector2(100,0));
            pathPoints.Add(new Vector2(200,100));
            Path path = new Path(pathPoints);
            Event_CreateEnemyWave target = new Event_CreateEnemyWave(enemies, formation, path, 0);
            LevelScript levelScript = new LevelScript(new List<ScriptedEvent>());
            GenericDrawableList drawableList = new GenericDrawableList();
            List<InterfaceComponent> components = new List<InterfaceComponent>();
            World world = new World(new Serialization.AchievementHandler(0, ""), drawableList, components, levelScript);
            Bounding visibleArea = new Bounding(new Vector2(0, 0), 1200, 800, true);
            Bounding useableArea = new Bounding(new Vector2(-301, -300), 1802, 1101, true);
            target.execute(world, visibleArea, useableArea);
            Assert.IsTrue(drawableList.getActors(typeof(Aircraft)).Count == 5);
            Rectangle expectedArea = new Rectangle(-1, -301, 802, 302);
            Point position;
            foreach (Aircraft aircraft in drawableList.getActors(typeof(Aircraft)))
            {
                Assert.IsTrue(aircraft.controller is AIControlledAircraft_PathGuided);
                position = new Point((int)aircraft.getGamePosition().X, (int)aircraft.getGamePosition().Y);
                Assert.IsTrue(expectedArea.Contains(position));
            }
        }

        [TestMethod()]
        public void getPendingEventsTest()
        {
            List<ScriptedEvent> eventList = new List<ScriptedEvent>();
            eventList.Add(new Event_SetMusic("song1", 0));
            eventList.Add(new Event_SetMusic("song1", 0));
            eventList.Add(new Event_SetMusic("song1", 1000));
            LevelScript levelscript = new LevelScript(eventList);
            GameTime gameTime = new GameTime(new System.TimeSpan(10000), new System.TimeSpan(10000));
            List<ScriptedEvent> pendingEvents;
            levelscript.Update(gameTime);
            pendingEvents = levelscript.getPendingEvents();
            Assert.IsTrue(pendingEvents.Count == 2, pendingEvents.Count.ToString());
            pendingEvents = levelscript.getPendingEvents();
            Assert.IsTrue(pendingEvents.Count == 0, pendingEvents.Count.ToString());
            gameTime = new GameTime(new System.TimeSpan(9980000), new System.TimeSpan(9980000));
            levelscript.Update(gameTime);
            pendingEvents = levelscript.getPendingEvents();
            Assert.IsTrue(pendingEvents.Count == 0, pendingEvents.Count.ToString());
            gameTime = new GameTime(new System.TimeSpan(30000), new System.TimeSpan(30000));
            levelscript.Update(gameTime);
            pendingEvents = levelscript.getPendingEvents();
            Assert.IsTrue(pendingEvents.Count == 1, pendingEvents.Count.ToString());
        }
    }

}
